﻿using DocumentFormat.OpenXml.Lite.Core.DocumentFS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using DocumentFormat.OpenXml.Lite.Helper;
using IO = System.IO;
using DocumentFormat.OpenXml.Lite.Core.Office;
using DocumentFormat.OpenXml.Lite.Shared;
using DocumentFormat.OpenXml.Lite.Core.Interfaces;

namespace DocumentFormat.OpenXml.Lite.Core.ContentType
{
    [XmlRoot("Types")]
    public class ContentTypeManager : ISerializable
    {
        [XmlElement("Default")]
        public List<Default> Defaults { get; set; }

        [XmlElement("Override")]
        public List<Override> Overrides { get; set; }

        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces Namespaces { get; set; }

        public ContentTypeManager()
        {
            Defaults = new List<Default>();
            Overrides = new List<Override>();

            Namespaces = new XmlSerializerNamespaces();
            Namespaces.Add(string.Empty, URI.ContentTypes.GetDescription());
        }

        public void CreateOverride(ContentType type, File target)
        {
            Overrides.Add(new Override()
            {
                ContentType = type.GetDescription(),
                PartName = "/" + target.GetXmlPath()
            });
        }

        public void CreateDefault(ContentType type, ExtensionType extension)
        {
            Defaults.Add(new Default()
            {
                ContentType = type.GetDescription(),
                Extension = extension.GetDescription()
            });
        }

        public void CreateDefaultForImage(Image image)
        {
            Defaults.Add(new Default()
            {
                ContentType = image.MimeType,
                Extension = image.ContentType
            });
        }

        #region ISerializable members

        public byte[] Serialize()
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType(), URI.ContentTypes.GetDescription());
            using (var stream = new IO.MemoryStream())
            {
                using (var writer = new IO.StreamWriter(stream, Encoding.UTF8))
                {
                    serializer.Serialize(writer, this, Namespaces);
                    return stream.ToArray();
                }
            }
        }

        public void Deserialize(System.IO.Stream content)
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType(), URI.ContentTypes.GetDescription());
            var cm = serializer.Deserialize(content) as ContentTypeManager;

            this.Defaults = cm.Defaults;
            this.Overrides = cm.Overrides;

            var supportedTags = Enum.GetValues(typeof(ContentType)).Cast<ContentType>().Select(e => e.GetDescription());
            this.Defaults.Where(d => !supportedTags.Contains(d.ContentType)).ToList().ForEach(d => this.Defaults.Remove(d));
            this.Overrides.Where(o => !supportedTags.Contains(o.ContentType)).ToList().ForEach(o => this.Overrides.Remove(o));
        }

        #endregion
    }
}
